<template>
    <div class="input-container">
        <input
            :type="type"
            class="input-control"
            @blur="testError"
            :value="value"
            @input="input"
            :class="{ 'is-invalid': inputRef.error }"
            :placeholder="placeholder"
            :style="{...inputStyle }"
        />
        <div v-if="inputRef.error" class="error-text" :style="{...inputStyle }">
            {{ inputRef.message }}
        </div>
    </div>
</template>

<script lang="ts" setup>
import { PropType, reactive } from "vue"
import { RuleProp } from "@types"
import { ruleStrategies } from "@/utils"

const emitFn = defineEmits(["update"])
const props = defineProps({
  type: {
    type: String,
    default: "text"
  },
  name: String,
  value: [String, Number, Boolean],
  placeholder: String,
  rules: Array as PropType<RuleProp[]>,
  inputStyle: Object
})

// 响应式错误信息
const inputRef = reactive({
  error: false,
  message: ""
})

// 检查错误
const testError = () => {
  if (props.rules) {
    const allPassed = props.rules.every((rule: RuleProp) => {
      let passed = true
      inputRef.message = rule.message
      passed = ruleStrategies[rule.type](props.value)
      return passed
    })
    inputRef.error = !allPassed
  }
}

// 传回数据
const input = (e: Event) => {
  const targetValue = (e.target as HTMLInputElement).value
  emitFn("update", { name: props.name, value: targetValue })
}
</script>

<style lang="less">
.input-container {
   .input-control{
      padding: 4px 10px;
      border-radius: @smallRadius;
      border: 1px solid @borderColor;
      align-items: center;
      font-size: 1em;
      &:focus{
         border: 1px solid @activeColor;
         outline: 2px solid @mainColor;
      }
   }
   .error-text{
      padding:6px 0 0 1px;
      color:@danger;
      text-align:left;
   }
}
</style>
